package com.serverapk.services;

import android.content.Context;

import com.alibaba.sdk.android.oss.ClientConfiguration;
import com.alibaba.sdk.android.oss.ClientException;
import com.alibaba.sdk.android.oss.OSS;
import com.alibaba.sdk.android.oss.OSSClient;
import com.alibaba.sdk.android.oss.ServiceException;
import com.alibaba.sdk.android.oss.callback.OSSCompletedCallback;
import com.alibaba.sdk.android.oss.callback.OSSProgressCallback;
import com.alibaba.sdk.android.oss.common.auth.OSSCredentialProvider;
import com.alibaba.sdk.android.oss.common.auth.OSSPlainTextAKSKCredentialProvider;
import com.alibaba.sdk.android.oss.internal.OSSAsyncTask;
import com.alibaba.sdk.android.oss.model.PutObjectRequest;
import com.alibaba.sdk.android.oss.model.PutObjectResult;
import com.serverapk.BaseApplication;
import com.serverapk.PostNex;
import com.serverapk.model.CachedThreadFactory;
import com.serverapk.model.Notify;
import com.serverapk.para.Common;
import com.serverapk.util.FileUtil;
import com.serverapk.util.L;
import com.serverapk.util.PrintToFileUtil;
import com.serverapk.util.SPUtils;
import com.serverapk.util.ToastUtil;

import org.greenrobot.eventbus.EventBus;

import java.io.File;

/**
 * Created by 葛健 on 2021/4/13.
 */

public class OssService {

    private OSS oss;
    private String accessKeyId;
    private String bucketName;
    private String accessKeySecret;
    private String endpoint;
    private Context context;

    private ProgressCallback progressCallback;
    private int cameraCount;

    public OssService(Context context, String accessKeyId, String accessKeySecret, String endpoint, String bucketName, int cameraCount) {
        this.context = context;
        this.endpoint = endpoint;
        this.bucketName = bucketName;
        this.accessKeyId = accessKeyId;
        this.accessKeySecret = accessKeySecret;
        this.cameraCount = cameraCount;

        initOSSClient();
    }

    public void initOSSClient() {
        //OSSCredentialProvider credentialProvider = new OSSStsTokenCredentialProvider("<StsToken.AccessKeyId>", "<StsToken.SecretKeyId>", "<StsToken.SecurityToken>");
        //这个初始化安全性没有Sts安全，如需要很高安全性建议用OSSStsTokenCredentialProvider创建（上一行创建方式）多出的参数SecurityToken为临时授权参数
        OSSCredentialProvider credentialProvider = new OSSPlainTextAKSKCredentialProvider(accessKeyId, accessKeySecret);
        ClientConfiguration conf = new ClientConfiguration();
        conf.setConnectionTimeout(15 * 1000); // 连接超时，默认15秒
        conf.setSocketTimeout(15 * 1000); // socket超时，默认15秒
        conf.setMaxConcurrentRequest(8); // 最大并发请求数，默认5个
        conf.setMaxErrorRetry(2); // 失败后最大重试次数，默认2次

        // oss为全局变量，endpoint是一个OSS区域地址
        oss = new OSSClient(context, endpoint, credentialProvider, conf);

    }

    public void beginupload(final Context context, String filename, String path, final int index,final String seq) {
        //通过填写文件名形成objectname,通过这个名字指定上传和下载的文件
        String objectname = filename;
        if (objectname == null || objectname.equals("")) {
            ToastUtil.showShort(context, "文件名不能为空");
            return;
        }
        //下面3个参数依次为bucket名，Object名，上传文件路径
        PutObjectRequest put = new PutObjectRequest(bucketName, objectname, path);
        if (path == null || path.equals("")) {
            L.e("请选择图片....");
            return;
        }
        L.e("正在上传中....");
        // 异步上传，可以设置进度回调
        put.setProgressCallback(new OSSProgressCallback<PutObjectRequest>() {
            @Override
            public void onProgress(PutObjectRequest request, long currentSize, long totalSize) {
                double progress = currentSize * 1.0 / totalSize * 100.f;
                if (progressCallback != null) {
                    progressCallback.onProgressCallback(progress);
                }
            }
        });
        @SuppressWarnings("rawtypes")
        OSSAsyncTask task = oss.asyncPutObject(put, new OSSCompletedCallback<PutObjectRequest, PutObjectResult>() {
            @Override
            public void onSuccess(PutObjectRequest request, PutObjectResult result) {
                L.e("uploadSuccess");
                //上传成功 回传结果通知接口
                if (cameraCount == 1) {
//                    PostNex.notifyPost(null, request.getObjectKey());
                    PostNex.notifyPostVideo(null, request.getObjectKey(), seq);


                    //只有一个摄像头 上传视频成功后 就删除你本地视频
                    final String name = request.getObjectKey();
                    final String name_264 = name.split("\\.")[0] + ".264";

                    //上传成功 删除本地保存的视频
                    CachedThreadFactory.getInstance().addTask(name, new Runnable() {
                        @Override
                        public void run() {
                            CachedThreadFactory.getInstance().removeTask(name);

                            File file = new File(Common.video_path + "/" + name);
                            FileUtil.deleteFile(file);
                            File file_264 = new File(Common.video_path + "/" + name_264);
                            FileUtil.deleteFile(file_264);

                        }
                    });

                } else if (cameraCount == 2) {
                    Notify notify = new Notify();
                    if (index == 1) {
                        notify.setIndex("1");
                    } else if (index == 2) {
                        notify.setIndex("2");
                    }
                    notify.setName(request.getObjectKey());
                    notify.setSuc(true);
                    EventBus.getDefault().post(notify);
                }


            }

            @Override
            public void onFailure(PutObjectRequest request, ClientException clientExcepion, ServiceException serviceException) {
                // 请求异常
                L.e("UploadFailure", clientExcepion.toString());
                if (clientExcepion != null) {
                    PostNex.errorPost(Common.error_code9, Common.error_info9 + "-" + request.getObjectKey() + ":" + clientExcepion.toString());
                    // 本地异常如网络异常等
                    L.e("UploadFailure：表示向OSS发送请求或解析来自OSS的响应时发生错误。\n" +
                            "  *例如，当网络不可用时，这个异常将被抛出");
                    clientExcepion.printStackTrace();
                }
                if (serviceException != null) {
                    PostNex.errorPost(Common.error_code9, Common.error_info9 + "-" + request.getObjectKey() + ":" + serviceException.toString());
                    // 服务异常
                    L.e("UploadFailure：表示在OSS服务端发生错误");
                    L.e("ErrorCode", serviceException.getErrorCode());
                    L.e("RequestId", serviceException.getRequestId());
                    L.e("HostId", serviceException.getHostId());
                    L.e("RawMessage", serviceException.getRawMessage());
                }

                if (cameraCount == 1) {
                    PostNex.notifyPost(null, "");
                    if (FileUtil.getFileOrFilesSize(Common.video_path, FileUtil.SIZETYPE_MB) >= FileUtil.MAX_MEMORY) {
                        CachedThreadFactory.getInstance().addTask(System.currentTimeMillis() + "", new Runnable() {
                            @Override
                            public void run() {
                                FileUtil.deleteFile(new File(Common.video_path));
                            }
                        });
                    }
//                    EventBus.getDefault().post("reupload");
                } else if (cameraCount == 2) {
                    Notify notify = new Notify();
                    if (index == 1) {
                        notify.setIndex("1");

                    } else if (index == 2) {
                        notify.setIndex("2");
                    }
                    notify.setName(request.getObjectKey());
                    notify.setSuc(false);
                    EventBus.getDefault().post(notify);
                }

//                SPUtils.put(context, "seq", Common.seq);
//                EventBus.getDefault().post("reupload");
            }
        });
        //task.cancel(); // 可以取消任务
//        task.waitUntilFinished(); // 可以等待直到任务完成

    }


    public ProgressCallback getProgressCallback() {
        return progressCallback;
    }

    public void setProgressCallback(ProgressCallback progressCallback) {
        this.progressCallback = progressCallback;
    }

    public interface ProgressCallback {
        void onProgressCallback(double progress);
    }

}
